package pgcoin

import (
	"context"
	"fmt"
	"gitee.com/bobo-rs/innovideo-services/enums"
	"gitee.com/bobo-rs/innovideo-services/framework/dao"
	"gitee.com/bobo-rs/innovideo-services/framework/model"
	"gitee.com/bobo-rs/innovideo-services/framework/service"
	"gitee.com/bobo-rs/innovideo-services/library/exception"
	"github.com/gogf/gf/v2/frame/g"
)

// GetBillList 获取账单列表
func (c *sPgCoin) GetBillList(ctx context.Context, in model.PGCoinBillListInput) (out *model.PGCoinBillListOutput, err error) {
	out = &model.PGCoinBillListOutput{}
	// 获取账单列表
	err = c.BillModel().ListAndTotal(ctx, model.CommonListAndTotalInput{
		Where: c.PGCoinBillWhere(in.PGCoinBillWhere),
		CommonPaginationItem: model.CommonPaginationItem{
			Page: in.Page,
			Size: in.Size,
		},
		Sort: fmt.Sprintf(`%s desc`, dao.PanguCoinBill.Columns().Id),
	}, &out.Rows, &out.Total)
	return
}

// GetBillDetail 获取账单详情
func (c *sPgCoin) GetBillDetail(ctx context.Context, billId uint) (out *model.PGCoinBillDetailOutput, err error) {
	out = &model.PGCoinBillDetailOutput{}
	// 获取账单详情
	detail, err := c.QueryBillDetail(ctx, billId)
	if err != nil {
		return nil, err
	}
	out.PGCoinBillDetailItem = *detail

	// 获取账单明细列表
	out.Items, _ = c.GetBillItemList(ctx, g.Map{
		dao.PanguCoinBillItem.Columns().BillId: billId,
	})
	return
}

// CorrectionUserAvailablePGCoin 根据盘古币账单为基础校正用户可用盘古币
func (c *sPgCoin) CorrectionUserAvailablePGCoin(ctx context.Context, uid uint) error {
	// 获取账户资金
	funds, err := service.User().GetFundsDetailByUid(ctx, uid)
	if err != nil {
		return err
	}

	// 获取账单数据
	bill, err := c.GetUserAvailablePGCoinBillList(ctx, uid)
	if err != nil {
		return err
	}

	// 账户资金盘古币等于账单可用盘古币一致
	if bill.TotalPGCoin == funds.AvailablePanguCoin {
		return exception.New(`账户资金盘古币和账单可用盘古币一致，无需校正`)
	}

	// 更新账户盘古币
	return service.User().UpdateFundsByUid(ctx, uid, g.Map{
		dao.UserFunds.Columns().AvailablePanguCoin: bill.TotalPGCoin,
	})
}

// GetUserAvailablePGCoinBillList 获取用户可用盘古币账单列表
func (c *sPgCoin) GetUserAvailablePGCoinBillList(ctx context.Context, uid uint) (out *model.UserAvailablePGCoinListOutput, err error) {
	out = &model.UserAvailablePGCoinListOutput{}
	// 获取可用的盘古币账单列表
	err = dao.PanguCoinBill.Ctx(ctx).
		Where(dao.PanguCoinBill.Columns().Uid, uid).
		Where(dao.PanguCoinBill.Columns().Status, enums.PGCoinBillStatusNormal).
		OrderAsc(dao.PanguCoinBill.Columns().ExpiredDate).
		Scan(&out.Rows)
	if err != nil {
		return nil, err
	}
	// 统计账单可用的盘古币数量
	for _, item := range out.Rows {
		out.TotalPGCoin += item.AvailablePanguCoin
	}
	return
}

// UpdatePGCoinBillComplete 盘古币消费完成-更新状态
func (c *sPgCoin) UpdatePGCoinBillComplete(ctx context.Context, idSet []uint) error {
	if len(idSet) == 0 {
		return nil
	}
	// 更新盘古币账单完成
	_, err := dao.PanguCoinBill.Ctx(ctx).
		Where(dao.PanguCoinBill.Columns().Id, idSet).
		Update(g.Map{
			dao.PanguCoinBill.Columns().AvailablePanguCoin: 0,
			dao.PanguCoinBill.Columns().Status:             enums.PGCoinBillStatusComplete,
		})
	if err != nil {
		return exception.New(`更新盘古币消费失败`)
	}
	return nil
}

// UpdateDeducePGCoinBill 更新减扣盘古币账单数量
func (c *sPgCoin) UpdateDeducePGCoinBill(ctx context.Context, id, moreCoin uint) error {
	if id == 0 {
		return exception.New(`减扣盘古币账单参数异常`)
	}
	data := g.Map{
		dao.PanguCoinBill.Columns().AvailablePanguCoin: moreCoin,
	}
	// 若是剩余盘古币为0，则账单全部消费，更新状态为交易完成
	if moreCoin == 0 {
		data[dao.PanguCoinBill.Columns().Status] = enums.PGCoinBillStatusComplete
	}
	_, err := dao.PanguCoinBill.Ctx(ctx).
		Where(dao.PanguCoinBill.Columns().Id, id).
		Update(data)
	if err != nil {
		return exception.New(`更新盘古币账单数量失败`)
	}
	return nil
}

// UpdateBillExpiredAt 更新盘古币账单效期
func (c sPgCoin) UpdateBillExpiredAt(ctx context.Context, in model.UpdateBillExpiredInput) error {
	// 更新账单效期
	return c.BillModel().Update(ctx, g.Map{
		dao.PanguCoinBill.Columns().Id: in.Id,
	}, g.Map{
		dao.PanguCoinBill.Columns().ExpiredDate: in.ExpiredAt,
		dao.PanguCoinBill.Columns().Remark:      in.Remark,
	})
}

// QueryBillDetail 查询账单详情
func (c *sPgCoin) QueryBillDetail(ctx context.Context, id uint) (detail *model.PGCoinBillDetailItem, err error) {
	if id == 0 {
		return nil, exception.New(`账单ID不能为空`)
	}
	detail = &model.PGCoinBillDetailItem{}
	// 获取账单详情
	err = c.BillModel().Scan(ctx, g.Map{
		dao.PanguCoinBill.Columns().Id: id,
	}, &detail)
	return
}
